using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace nBodyPhone
{
    class Body
    {
        Game1 game;
        public Color color;
        public Texture2D texture;
        public Vector2 position;
        public Vector2 texturePosition;
        public Vector2 velocity;
        public Vector2 distance;
        public Vector2 force;
        public Vector2 move;
        public float mass;
        public float radius;
        public bool alive;

        public Body(Color color, Texture2D texture, Vector2 position, Vector2 velocity, float mass, float radius)
        {
            this.color = color;
            this.texture = texture;
            this.position = position;
            this.texturePosition = new Vector2(position.X - texture.Width / 2, position.Y - texture.Height / 2);
            this.velocity = velocity;
            this.mass = mass;
            this.radius = radius;
            this.alive = true;
        }

        public void updateVelocity(Vector2 velocity)
        {
            this.velocity = velocity;
        }

        public void updatePosition(Vector2 position)
        {
            this.position = position;
            this.texturePosition = new Vector2(position.X - texture.Width / 2, position.Y - texture.Height / 2);
        }

        public string toString()
        {
            string info = "<vel(" + this.velocity.ToString() + ") mass(" + this.mass.ToString() + ")>";
            return info;
        }

        public void ResolveCollision(Body body)
        {
            Vector2 Dn = this.position - body.position;

            // The distance between the balls
            float delta = Dn.Length();

            // The normal vector of the collision plane
            Dn.Normalize();

            // The tangential vector of the collision plane
            Vector2 Dt = new Vector2(Dn.Y, -Dn.X);

            // avoid division by zero
            if (delta == 0)
            {
                body.position += new Vector2(0.01f, 0);
                return;
            }

            //the masses of the two balls
            float m1 = this.mass;
            float m2 = body.mass;
            float M = m1 + m2;

            // minimum translation distance to push balls apart after intersecting
            Vector2 mT = Dn * ((this.radius + body.radius - delta));

            // push the balls apart proportional to their mass
            //this.position = this.position + (mT * m2 / M);
            //body.position = body.position - (mT * m1 / M);

            // the velocity vectors of the balls before the collision
            Vector2 v1 = this.velocity;
            Vector2 v2 = body.velocity;

            // split the velocity vector of the first ball into a normal and a
            // tangential component in respect of the collision plane
            Vector2 v1n = Dn * Vector2.Dot(v1, Dn);
            Vector2 v1t = Dt * Vector2.Dot(v1, Dt);

            // split the velocity vector of the second ball into a normal and a
            // tangential component in respect of the collision plane
            Vector2 v2n = Dn * Vector2.Dot(v2, Dn);
            Vector2 v2t = Dt * Vector2.Dot(v2, Dt);

            // calculate new velocity vectors of the balls, the tangential component
            // stays the same, the normal component changes analog to the 1-Dimensional case
            this.velocity = v1t + Dn * ((m1 - m2) / M * v1n.Length() + 2 * m2 / M * v2n.Length());
            body.velocity = v2t - Dn * ((m2 - m1) / M * v2n.Length() + 2 * m1 / M * v1n.Length());
        }
    }
}
